#pragma once
#ifndef _VFS_TESTS_H_
#define _VFS_TESTS_H_
#include <gtest/gtest.h>
#include "resource_system/vfs/vfs.h"
#include "core/exception/lpeException.h"
#include <boost/filesystem.hpp>

// invalid path causes an exception.
TEST(VFS, init_invalidPathCausesThrow)
{
	lpe::resman::CVirtualFileSystem vfs;
	EXPECT_THROW(vfs.init("NOT_EXISTS"),lpe::core::fileManagementException);
}

// Correct path causes good behaivour
TEST(VFS, init_correctPathCausesNoThrow)
{
	lpe::resman::CVirtualFileSystem vfs;
	EXPECT_NO_THROW(vfs.init(boost::filesystem::current_path().string().c_str()));
}

// You cannot init twice
// This test doesn't works correctly on windows
#ifndef _WIN32

TEST(VFS, init_callTwiceCausesAssert)
{
	lpe::resman::CVirtualFileSystem vfs;
	EXPECT_NO_THROW(vfs.init(boost::filesystem::current_path().string().c_str()));
	EXPECT_DEATH(vfs.init(boost::filesystem::current_path().string().c_str()),"");

}

#endif //_WIN32


TEST(VFS, init_afterInitVFSIsInitialized)
{
	lpe::resman::CVirtualFileSystem vfs;
	vfs.init(boost::filesystem::current_path().string().c_str());
	EXPECT_TRUE(vfs.isInitialized());
}
TEST(VFS, setSystemResourcesBasePath_returnsCompletePathOnCompletePath)
{
	lpe::resman::CVirtualFileSystem vfs;
	vfs.init(boost::filesystem::current_path().string().c_str());

	EXPECT_EQ(vfs.getSystemResourcesBasePath(),boost::filesystem::current_path().string());
}

TEST(VFS, createSubPath_throwIfNotInicialized)
{
	lpe::resman::CVirtualFileSystem vfs;
	EXPECT_THROW(vfs.createSubPath("temp"), lpe::core::uninitializedComponentException);
}

TEST(VFS, createSubPath_subpathCreatedIntoBasePAth)
{
	lpe::resman::CVirtualFileSystem vfs;
	boost::filesystem::path pp(boost::filesystem::current_path());
	pp /= boost::filesystem::path("temp");
	if(!boost::filesystem::exists(pp))
	{
		boost::filesystem::create_directory(pp);
	}

	vfs.init("temp");
	vfs.createSubPath("temp2");
	boost::filesystem::path p(vfs.getSystemResourcesBasePath());
	p /= boost::filesystem::path("temp2");
	EXPECT_TRUE(boost::filesystem::exists(p));
}

TEST(VFS, createSubPath_createsDeeperFolders)
{
	lpe::resman::CVirtualFileSystem vfs;
	boost::filesystem::path pp(boost::filesystem::current_path());
	pp /= boost::filesystem::path("temp");
	if(!boost::filesystem::exists(pp))
	{
		boost::filesystem::create_directory(pp);
	}

	vfs.init("temp");
	vfs.createSubPath("temp2/temp3/temp4");
	boost::filesystem::path p(vfs.getSystemResourcesBasePath());
	p /= boost::filesystem::path("temp2/temp3/temp4");
	EXPECT_TRUE(boost::filesystem::exists(p));
}

class VFSFixtureTest : public ::testing::Test
{
public:

	const std::string TEST_APP;
	lpe::resman::CVirtualFileSystem m_vfs;

	void SetUp()
	{
		// setting up virtual file system
		m_vfs.init("./media", false);
		m_vfs.setWriteDirectory("files");
		m_vfs.addLocationToSearch("data", 0);

		// creating dummyfile
		std::ofstream outFile;
		outFile.open("./media/data/test_data.txt");
		if(!outFile.is_open())
			return;
		outFile << "This is a sample data";
		outFile.close();
	}
	void TearDown()
	{
		m_vfs.reset();
	}

	VFSFixtureTest()
		:TEST_APP("[TEST]")
	{
	}

	virtual ~VFSFixtureTest(){

	}
};

TEST_F(VFSFixtureTest,setDeployPolicy_can_set_deploy_file_policy)
{
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_NORMAL));
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_SHADOW));
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_SHADOW_WITH_EXTENSION));
}
TEST_F(VFSFixtureTest,getDeployPolicy_can_get_deploy_file_policy)
{
	lpe::resman::CVirtualFileSystem::DEPLOY_MODE mode = lpe::resman::CVirtualFileSystem::DPMOD_SHADOW;
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_SHADOW));
	EXPECT_EQ(mode, m_vfs.getDeployPolicy());
}
TEST_F(VFSFixtureTest,deployFile_deploys_following_default_deploy_policy_normal)
{
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_NORMAL));
	boost::filesystem::path p("./media/files/test_data.txt");
	p = boost::filesystem::system_complete(p);
	EXPECT_EQ(p,m_vfs.deployFile("test_data.txt"));
}
TEST_F(VFSFixtureTest,deployFile_deploys_following_parameter_deploy_policy_normal)
{
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_SHADOW));
	boost::filesystem::path p("./media/files/test_data.txt");
	p = boost::filesystem::system_complete(p);
	EXPECT_EQ(p,m_vfs.deployFile("test_data.txt",lpe::resman::CVirtualFileSystem::DPMOD_NORMAL));
}
TEST_F(VFSFixtureTest,deployFile_deploys_following_default_deploy_policy_shadow)
{
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_SHADOW));
	boost::filesystem::path p("./media/files/e76973b2035fe772d2716d71ce7df441");
	p = boost::filesystem::system_complete(p);
	EXPECT_EQ(p.string(),m_vfs.deployFile("test_data.txt"));
}

TEST_F(VFSFixtureTest,deployFile_deploys_following_parameter_deploy_policy_shadow)
{
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_NORMAL));
	boost::filesystem::path p("./media/files/e76973b2035fe772d2716d71ce7df441");
	p = boost::filesystem::system_complete(p);
	EXPECT_EQ(p,m_vfs.deployFile("test_data.txt",lpe::resman::CVirtualFileSystem::DPMOD_SHADOW));
}
TEST_F(VFSFixtureTest,deployFile_deploys_following_default_deploy_policy_shadow_w_extension)
{
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_SHADOW_WITH_EXTENSION));
	boost::filesystem::path p("./media/files/6af8307c2460f2d208ad254f04be4b0d.txt");
	p = boost::filesystem::system_complete(p);
	EXPECT_EQ(p.string(),m_vfs.deployFile("test_data.txt"));
}

TEST_F(VFSFixtureTest,deployFile_deploys_following_parameter_deploy_policy_shadow_w_extension)
{
	EXPECT_NO_THROW(m_vfs.setDeployPolicy(lpe::resman::CVirtualFileSystem::DPMOD_NORMAL));
	boost::filesystem::path p("./media/files/6af8307c2460f2d208ad254f04be4b0d.txt");
	p = boost::filesystem::system_complete(p);
	EXPECT_EQ(p,m_vfs.deployFile("test_data.txt",lpe::resman::CVirtualFileSystem::DPMOD_SHADOW_WITH_EXTENSION));
}
#endif //_VFS_TESTS_H_
